from django.db import models
from django_mysql import models as mysql_models


# 权限表模型类
class Permission(models.Model):
    # 请求方式
    method_choices = [
        ('get', '查询'),
        ('post', '创建'),
        ('put', '更新'),
        ('patch', '部分更新'),
        ('delete', '删除')
    ]
    parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL, related_name='children',
                               verbose_name='父级权限')
    name = models.CharField(max_length=50, unique=True, verbose_name='权限名称')
    code = models.CharField(max_length=50, unique=True, verbose_name='权限编码')
    url = models.CharField(max_length=50, verbose_name='地址')
    method = models.CharField(max_length=10, choices=method_choices, verbose_name='访问方式')
    # category = models.CharField(max_length=20, choices=category_choices, verbose_name='分类')
    # PositiveSmallIntegerField: 表示无符号smallint
    status = models.BooleanField(default=True, verbose_name='状态')

    class Meta:
        db_table = 'sys_permission'


# 角色数据表模型类
class Role(models.Model):
    # 设置多对多关联
    permission = models.ManyToManyField(Permission, through='RolePermission', related_name='role')
    name = models.CharField(max_length=50, verbose_name='角色名称')
    remark = models.CharField(max_length=5, verbose_name='角色备注')
    status = models.BooleanField(default=True, verbose_name='角色状态')
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        db_table = 'sys_role'


# 管理员账号表模型类
class User(models.Model):
    # through:指定中间表模型类名称,字符串格式, 也可以不指定, 除非中间表中除了外键字段之前还有其他字段
    # related_name: 指定反向查询时,如何访问当前数据表中的关联数据, 默认使用`小写模型名_set`属性来访问
    role = models.ManyToManyField(Role, through='UserRole', related_name='users')
    username = models.CharField(max_length=50, unique=True, verbose_name='账号')
    password = models.CharField(max_length=50, verbose_name='密码')
    phone = models.CharField(max_length=11, unique=True, verbose_name='手机号码')
    email = models.CharField(max_length=50, unique=True, verbose_name='电子邮箱')
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    status = models.BooleanField(default=True, verbose_name='账号状态')

    class Meta:
        db_table = 'sys_user'
        # 设置排序方式
        ordering = ('-create_time',)
        # 设置联合唯一索引
        # unique_together = (('username','email'),)
        # django-2.2版本以上推荐使用如下方式设置联合唯一索引
        # constraints = [models.UniqueConstraint(fields=['username','email'],name='unique'),]


# 用户角色表(中间表)模型类
class UserRole(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    role = models.ForeignKey(Role, on_delete=models.RESTRICT)

    class Meta:
        db_table = 'sys_user_role'


#   角色权限表模型类
class RolePermission(models.Model):
    # 设置外键关联
    # 角色被删除的时候, role_id对应数据被删除
    role = models.ForeignKey(Role, on_delete=models.CASCADE)
    # 权限被删除的时候, permission_id字段对应数据被删除
    permission = models.ForeignKey(Permission, on_delete=models.CASCADE)
    class Meta:
        db_table = 'sys_role_permission'
        # 设置排序方式
        ordering = ('id',)


#   菜单表模型类
class Menu(models.Model):
    # 导航类型
    menuTypes=[('dir', '目录'), ('nav', '导航'), ('link', '链接')]
    title = models.CharField(max_length=20, unique=True, verbose_name='菜单标题')
    path = models.CharField(max_length=100,null=True,blank=True, verbose_name='页面地址')
    parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL, related_name='children',
                               verbose_name='父级菜单')
    icon = models.CharField(max_length=200,null=True,blank=True, verbose_name='菜单图标')
    permission = models.ForeignKey(Permission, null=True, on_delete=models.SET_NULL,verbose_name='权限')
    menu_type = models.CharField(max_length=20, choices=menuTypes,default='nav', verbose_name='菜单类型')
    status = models.BooleanField(default=1, verbose_name='状态')
    sort_order = models.PositiveSmallIntegerField(default=0, verbose_name='排序')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间')
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'sys_menu'
